/*!
   \file

   \brief
        Contains ObjectStore<type>, a class that stores objects, returning handles to them when
        objects are added.

   © 2011 Mark W. Gabby II

   This file is part of the Avion engine.

   The Avion engine is free software: you can redistribute it and/or modify it under the terms of
   the GNU General Public License as published by the Free Software Foundation, either version 3 of
   the License, or (at your option) any later version.

   The Avion engine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
   without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
   the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along with the Avion Engine.
   If not, see <http://www.gnu.org/licenses/>.
*/
//********
/*!

   \file

   © 2011 Mark W. Gabby II
*/
#pragma once
#include <map>
#include <list>

#include "Util/GlobalConstants.hpp"

/*!
   \brief
      This class stores objects. When objects are added, handles to the objects are sent back.

   \note
      This class stores pointers to objects, not the objects themselves.
      It does NOT allocate or deallocate memory, however.
*/
template< typename type >
class ObjectStore
{
public:
   typedef typename std::map<uint32_t, type *>::iterator iterator;

   ObjectStore()
   {
      map.clear();
      nextHandle = 0;
   }

   uint32_t AddObject( type * ToAdd )
   {
      uint32_t NewHandle = nextHandle;
      ++nextHandle;
      map[NewHandle] = ToAdd;

      return NewHandle;
   }

   type * RemoveObject( uint32_t ObjectHandle )
   {
      type * Object = map[ObjectHandle];
      map.erase( ObjectHandle );

      return Object;
   }

   type * GetObject( uint32_t ObjectHandle )
   {
      return (*this)[ObjectHandle];
   }

   iterator Begin()
   {
      return map.begin();
   }

   iterator End()
   {
      return map.end();
   }

   void Clear()
   {
      map.clear();
   }

   uint32_t Size()
   {
      return map.size();
   }

   type * operator[]( uint32_t ObjectHandle )
   {
      ObjectStore::iterator it = map.find( ObjectHandle );

      if ( it != map.end() )
      {
         return ( *it ).second;
      }
      else
      {
         return 0;
      }
   }

private:
   std::map<uint32_t, type *> map;
   uint32_t nextHandle;
};
